package com.kkshop.integration.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContextException;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;

public abstract class AbstractDetectingUrlHandlerMapping extends AbstractUrlHandlerMapping {

    private boolean detectHandlersInAncestorContexts = false;

    public void setDetectHandlersInAncestorContexts(boolean detectHandlersInAncestorContexts) {
        this.detectHandlersInAncestorContexts = detectHandlersInAncestorContexts;
    }

    public void initApplicationContext() throws ApplicationContextException {
        super.initApplicationContext();
        detectHandlers();
    }

    protected void detectHandlers() throws BeansException {
        if (logger.isDebugEnabled()) {
            logger.debug("Looking for URL mappings in application context: " + getApplicationContext());
        }
        
        String[] beanNames = (detectHandlersInAncestorContexts ?
                BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(),Object.class) :
                    getApplicationContext().getBeanNamesForType(Object.class));

        for (int i = 0; i < beanNames.length; i++) {
            String beanName = beanNames[i];
            String[] urls = determineUrlsForHandler(beanName);

            if (!ObjectUtils.isEmpty(urls)) {
                registerHandler(urls, beanName);
            } else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Rejected bean name '" + beanNames[i] + "': no URL paths identified");
                }
            }
        }
    }

    protected abstract String[] determineUrlsForHandler(String beanName);
}
